package com.jrx.anytxn.transaction.job.coupon.step;

import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.customer.constant.CustomerConstant;
import com.jrx.anytxn.customer.dto.customer.CustomerFirstLevelRes;
import com.jrx.anytxn.customer.entity.CmCustomerBankcardInfo;
import com.jrx.anytxn.customer.entity.CmCustomerRightInfo;
import com.jrx.anytxn.customer.entity.CmCustomerSecondLevel;
import com.jrx.anytxn.customer.entity.TlCouponDetail;
import com.jrx.anytxn.customer.service.ICustomerService;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.ErrorMsgConstant;
import com.jrx.anytxn.param.entity.PrActivityInfo;
import com.jrx.anytxn.param.entity.PrRightsAndInterests;
import com.jrx.anytxn.param.enums.RightsEffectivePeriodInActivityEnum;
import com.jrx.anytxn.param.service.rights.IPrActivityInfoService;
import com.jrx.anytxn.param.service.rights.IPrRightsAndInterestsService;
import com.jrx.anytxn.transaction.config.CouponConfig;
import com.jrx.anytxn.transaction.job.coupon.dto.CustomerRightsDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * ClassName CompensationActivateProcessor
 *
 * @author lujianyou zebin.zhang
 * @version 1.0
 * @description 补偿激活时未送120元优惠批处理 - PROCESSOR
 * @date 2022/02/11 16:55
 **/
@Service
@Slf4j
public class CompensationActivateProcessor implements ItemProcessor<CmCustomerBankcardInfo, CustomerRightsDTO> {
    private static final Integer COUPON_TOTAL_TO_SEND = 12;
    private static final String PRODUCT_CODE = "XIBXAH000001";

    @Autowired
    private CouponConfig couponConfig;

    @Autowired
    private ISegmentService segmentService;
    @Autowired
    private IPrRightsAndInterestsService rightsAndInterestsService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private IPrActivityInfoService activityInfoService;

    @Override
    public CustomerRightsDTO process(CmCustomerBankcardInfo bankCardInfo) throws Exception {
        String customerId = bankCardInfo.getCustomerId();
        String tenantId = bankCardInfo.getTenantId();
        List<CmCustomerSecondLevel> customerSecondLevels = customerService.getSecondByCustomerIdAndTensnId(customerId, tenantId);
        CmCustomerSecondLevel customerSecondLevel = customerSecondLevels.get(0);
        String subChannel = customerSecondLevel.getSubChannel();
        //设置默认活动ID
        String activityId = couponConfig.getActivity().getChannelMissing();
        //通过邀新渠道激活
        if (StringUtils.isNotBlank(customerSecondLevel.getRecommenderCode())) {
            activityId = couponConfig.getActivity().getMGM();
        }
        //通过其他渠道激活
        else if (!StringUtils.isBlank(subChannel)) {
            String tempActivityId = couponConfig.getActivity().getChannels().get(subChannel);
            if (StringUtils.isNotBlank(tempActivityId)) {
                activityId = tempActivityId;//将活动ID替换成对应渠道的活动ID
            }
        }

        PrActivityInfo activityInfo = activityInfoService.getByTenantIdAndActivityId(tenantId, activityId);
        if (null == activityInfo) {
            return null;
        }
        Integer rightsQuantity = activityInfo.getRightsQuantity();
        String rightsIds = activityInfo.getRightsId();
        int buyQuantity = activityInfo.getRightsQuantity();
        if (StringUtils.isBlank(rightsIds)) {
            return null;
        }
        String[] rightsIdsArr = rightsIds.split(",");

        LinkedHashSet<String> rightsLinkedHashSet = new LinkedHashSet<>();//用来存放去重后有序的rightIds
        Map<String, Integer> rightsMap = new HashMap<>();//用来存放每个rightsId发放的数量
        Map<String, PrRightsAndInterests> rightsInfoMap = new HashMap<>();//用来存放每个rightsId对应的权益信息
        for (int i = 0; i < rightsIdsArr.length; i++) {
            rightsLinkedHashSet.add(rightsIdsArr[i]);//
            if (rightsMap.containsKey(rightsIdsArr[i])) {
                rightsMap.put(rightsIdsArr[i], rightsMap.get(rightsIdsArr[i]) + 1);
            } else {
                if (rightsIdsArr.length > 1) {
                    rightsMap.put(rightsIdsArr[i], 1);
                } else {//只有一个rightsId的情况，直接扣减活动表里配置的下发数量
                    rightsMap.put(rightsIdsArr[i], rightsQuantity);
                }
            }
        }

        List<CmCustomerRightInfo> customerRightInfoList = new ArrayList<>();
        List<TlCouponDetail> couponDetailList = new ArrayList<>();
        log.info("---组装客户权益信息---");
        for (int i = 0; i < rightsIdsArr.length; i++) {
            try {
                PrRightsAndInterests prRightsAndInterests = rightsAndInterestsService.checkRightsAndInterests(tenantId,
                        rightsIdsArr[i], PRODUCT_CODE);
                if (!rightsInfoMap.containsKey(prRightsAndInterests.getRightsId())) {
                    rightsInfoMap.put(prRightsAndInterests.getRightsId(), prRightsAndInterests);
                }
                CmCustomerRightInfo cmCustomerRightInfo = generateCustomerRight(bankCardInfo, prRightsAndInterests, activityId);
                if(i == 0){//有多个权益时，在setMonthslyTypeProp中组装
                    customerRightInfoList.add(cmCustomerRightInfo);
                }
                if (RightsEffectivePeriodInActivityEnum.MONTHSLY.getCode().equals(activityInfo.getRightsEffectivePeriod())) {//往后连月发放，做特殊处理
                    if (rightsIdsArr.length > 1) {//配置了多个rightsId
                        if (buyQuantity != rightsIdsArr.length) {
                            throw new TxnBizException(TxnRespCode.ACTIVITY_RIGHTS_QUANTITY_MISMATCHED);
                        }
                        setMonthslyTypeProp(i, cmCustomerRightInfo, customerRightInfoList, false);
                    } else {//只配置了一个rightsId
                        for (int j = 0; j < buyQuantity; j++) {
                            setMonthslyTypeProp(j, cmCustomerRightInfo, customerRightInfoList, true);
                        }
                    }
                }
            } catch (Exception e) {
                log.info("Exception:", e);
                return null;
            }
        }
        couponDetailList = generateCouponDetail(bankCardInfo, customerRightInfoList);

        CustomerRightsDTO customerRightsDTO = new CustomerRightsDTO();
        customerRightsDTO.setTlCouponDetailList(couponDetailList);
        customerRightsDTO.setCmCustomerRightInfoList(customerRightInfoList);
        customerRightsDTO.setRightsLinkedHashSet(rightsLinkedHashSet);
        customerRightsDTO.setRightsMap(rightsMap);
        customerRightsDTO.setRightsInfoMap(rightsInfoMap);
        return customerRightsDTO;
    }


    /**
     * 生成 客户权益信息记录
     *
     * @param item
     * @return
     */
    private CmCustomerRightInfo generateCustomerRight(CmCustomerBankcardInfo item, PrRightsAndInterests prRightsAndInterests, String activityId) throws TxnException {
        CmCustomerRightInfo customerRight = new CmCustomerRightInfo();

        Date today = new Date();
        Date monthStart = DateUtils.getMonthStartTime(today);
        Date monthEnd = DateUtils.getMonthEndTime(today);

        try {
            Long id = segmentService.getId(CustomerConstant.CM_CUSTOMER_RIGHT_INFO);
            log.info("当前生成的CM_CUSTOMER_RIGHT_INFO——ID为：" + id);
            customerRight.setId(id);
        } catch (SegmentException e) {
            log.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }

        customerRight.setTenantId(item.getTenantId());
        customerRight.setChannel(item.getChannel());
        customerRight.setCustomerId(item.getCustomerId());
        customerRight.setRightsId(prRightsAndInterests.getRightsId());
        customerRight.setOrganizationId(item.getOrganizationId());
        customerRight.setEffectDate(monthStart);
        customerRight.setExpiresDate(monthEnd);
        customerRight.setRightsType(prRightsAndInterests.getRightsType());
        customerRight.setRightsName(prRightsAndInterests.getRightsName());
        customerRight.setAllowProducts(PRODUCT_CODE);
        customerRight.setLoanId("");
        customerRight.setRightsStatus(CustomerConstant.RIGHTS_STATUS_0);
        customerRight.setCreateTime(today);
        customerRight.setUpdateTime(today);
        customerRight.setUpdateBy(item.getCustomerId());
        customerRight.setRecordVersionNumber(1);
        customerRight.setActivityId(activityId);
        customerRight.setRightsQuantity(0);
        customerRight.setProductCode(PRODUCT_CODE);
        customerRight.setFaceValue(prRightsAndInterests.getFaceValue());
        customerRight.setThresholdPrice(prRightsAndInterests.getThresholdPrice());
        customerRight.setDiscountValue(prRightsAndInterests.getDiscountValue());
        customerRight.setDiscountsCeiling(prRightsAndInterests.getDiscountsCeiling());
        customerRight.setCycleUse(prRightsAndInterests.getCycleUse());
        customerRight.setDiscountAmtLimit(prRightsAndInterests.getDiscountAmtLimit());
        return customerRight;
    }

    private List<TlCouponDetail> generateCouponDetail(CmCustomerBankcardInfo cmCustomerBankcardInfo, List<CmCustomerRightInfo> customerRightInfoList) throws TxnException {
        List<TlCouponDetail> tlCouponDetailList = new ArrayList<>();
        for (CmCustomerRightInfo cmCustomerRightInfo : customerRightInfoList) {
            TlCouponDetail couponDetail = new TlCouponDetail();
            try {
                Long id = segmentService.getId(CustomerConstant.TL_COUPON_DETAIL_INFO);
                couponDetail.setId(id);
            } catch (SegmentException e) {
                log.error("主键生成错误", e);
                throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
            }
            CustomerFirstLevelRes firstLevelRes = customerService.getFirstLevelByOrgIdAndCusId(cmCustomerBankcardInfo.getCustomerId(), cmCustomerBankcardInfo.getOrganizationId(), cmCustomerBankcardInfo.getTenantId());

            couponDetail.setTenantId(cmCustomerBankcardInfo.getTenantId());
            couponDetail.setOrganizationId(cmCustomerBankcardInfo.getOrganizationId());
            couponDetail.setChannel(cmCustomerBankcardInfo.getChannel());
            couponDetail.setCustomerId(cmCustomerBankcardInfo.getCustomerId());
            couponDetail.setCustomerRightsId(cmCustomerRightInfo.getId());
            couponDetail.setIdNumber(firstLevelRes.getIdNumber());
            couponDetail.setChineseName(firstLevelRes.getChineseName());
            couponDetail.setMobile(cmCustomerBankcardInfo.getMobile());
            couponDetail.setRightsId(cmCustomerRightInfo.getRightsId());
            couponDetail.setRightsName(cmCustomerRightInfo.getRightsName());
            couponDetail.setRightsType(cmCustomerRightInfo.getRightsType());
            couponDetail.setCreateTime(new Date());
            couponDetail.setUpdateTime(new Date());
            couponDetail.setUpdateBy(firstLevelRes.getCustomerId());
            couponDetail.setCouponSummaryId(0L);
            couponDetail.setRecordVersionNumber(1);
            couponDetail.setActivityId(cmCustomerRightInfo.getActivityId());
            tlCouponDetailList.add(couponDetail);
        }
        return tlCouponDetailList;
    }

    private CmCustomerRightInfo setMonthslyTypeProp(int i, CmCustomerRightInfo cmCustomerRightInfo, List<CmCustomerRightInfo> cmCustomerRightInfoList, Boolean flag) throws TxnBizException {
        Date initEffectiveDate = cmCustomerRightInfo.getEffectDate();
        Date initExpireDate = cmCustomerRightInfo.getExpiresDate();
        CmCustomerRightInfo tmp = new CmCustomerRightInfo();
        BeanUtils.copyProperties(cmCustomerRightInfo, tmp);
        // 设置连月的id、生效日期、失效日期
        if (i > 0) {
            if (flag) {
                try {
                    Long id = segmentService.getId(CustomerConstant.CM_CUSTOMER_RIGHT_INFO);
                    log.info("当前生成的CM_CUSTOMER_RIGHT_INFO——ID为：" + id);
                    tmp.setId(id);
                } catch (SegmentException e) {
                    log.error("主键生成错误", e);
                    throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
                }
            }
            tmp.setEffectDate(DateUtils.addMonth(initEffectiveDate, i));
            tmp.setExpiresDate(DateUtils.addMonth(initExpireDate, i));
            cmCustomerRightInfoList.add(tmp);
        }
        return tmp;
    }
}
